package models.application;

import java.util.List;

import javax.persistence.*;

import com.avaje.ebean.*;
import com.avaje.ebean.Query;
import com.avaje.ebean.validation.*;

import models.pubobj.AniHttpMethod;
import models.pubobj.AniObjectState;

import models.pubobj.AniObjectType;
import org.apache.commons.lang3.StringUtils;
import play.db.ebean.*;

@Entity
public class AniApi extends Model {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8420449264626696520L;

	@Id
	public Long id;
	
	@ManyToOne
	@NotNull
	public AniApp hostApp;
	
	@ManyToOne
	@NotNull
	public AniObjectState state;

    @ManyToOne
    @NotNull
    public AniObjectType type;
	
    @NotNull
	public String apiName;
	
    @NotNull
	public String url;
	
	@ManyToOne
	@NotNull
	public AniHttpMethod method;
	
	public String description;
	
	@OneToMany(mappedBy="hostApi")
	public List<AniApiParam> params;

    public AniApi(AniApp hostApp, AniObjectState state, AniObjectType type, String apiName, String url, AniHttpMethod method, String description) {
        this.hostApp = hostApp;
        this.state = state;
        this.type = type;
        this.apiName = apiName;
        this.url = url;
        this.method = method;
        this.description = description;
    }

    public AniApi(Long id) {
        this.id = id;
    }

    public static Model.Finder<Long, AniApi> find = new Model.Finder<Long, AniApi>(Long.class, AniApi.class);

    public static Query<AniApi> finder(){
        return find
                .fetch("hostApp")
                .fetch("type")
                .fetch("state")
                .fetch("method");
    }

    private static AniObjectState getRetiredState(){
        return AniObjectState.findByStateKey(
                AniObjectState.States.RETIRED.name()
        );
    }

	public static List<AniApi> findAll() {
        return finder().findList();
    }

    public static List<AniApi> findByApiName(String apiName, AniApp parentApp) {
        return finder().where()
                .eq("apiName", apiName.trim())
                .eq("hostApp.id", parentApp.id)
                .ne("state.id", getRetiredState().id)
                .findList();
    }

    public static Integer getEntityNum(AniApi oneApi){
        Integer entityNum = 0;
        if(oneApi.id != null){
            entityNum = finder().where()
                    .idEq(oneApi.id)
                    .ne("state.id", getRetiredState().id)
                    .findRowCount();
        }
        if(entityNum < 1 && !StringUtils.isEmpty(oneApi.apiName)){
            entityNum = finder().where()
                    .eq("apiName", oneApi.apiName.trim())
                    .eq("hostApp.id", oneApi.hostApp.id)
                    .ne("state.id", getRetiredState().id)
                    .findRowCount();
        }
        return entityNum;
    }

    public static AniApi getById(Long apiId){
        return finder().where().idEq(apiId).findUnique();
    }

    public static List<AniApi> findByHostApp(AniApp hostApp){
        return finder().where()
                .eq("hostApp.id", hostApp.id)
                .ne("state.id", getRetiredState().id)
                .findList();
    }

    public static void deleteWithEntity(AniApi oneApi){
        oneApi.state = AniObjectState.findByStateKey(
                AniObjectState.States.RETIRED.name()
        );
        oneApi.update();
    }
}
